
import Promise from 'bluebird'
import moment from 'moment'
import { Protobuffer, Socket } from 'gm-api-sdk'
import _ from 'lodash'
import { proto } from '../config'
import protoApi from '../config/proto-api'
import { CODE, ErrorInfo } from '../error'
import { callback } from '../utils'

const { rtsp, options } = proto

export const asyncSend = (name, otps = {}, rtsp_key = undefined) => {
  let useRtsp = undefined
  if (_.has(proto, 'rtsps') && rtsp_key) {
    let rtspKeys = _.keys(proto.rtsps)
    if (rtspKeys.indexOf(rtsp_key) === -1) {
      rtsp_key = rtspKeys[0]
    }
    useRtsp = proto.rtsps[rtsp_key]
  }
  const socket = new Socket(useRtsp || rtsp)
  const protobuffer = new Protobuffer(options)
  const { createPBBuffer, makeData, decode, gameMessage } = protobuffer
  let protoSett = getProtoSett(name)
  return new Promise((resolve, reject) => callback(resolve, reject, isProtoSett(protoSett), null))
    .then( () => {
      let { code, request } = protoSett
      let data = makeData(createPBBuffer(code, request, otps))
      return socket.send(data)
    })
    .then( buffer => {
      let messageQuery = gameMessage(protoSett.response)
      let msgBase = decode(buffer, messageQuery)
      let { msghead, msgbody } = msgBase
      return { msghead, msgbody }
    })
}

const getProtoSett = name => {
  let protoSett = _.find(protoApi, o => o.name === name)
  if (protoSett) {
    if (_.has(protoSett, 'request') && !/\./.test(protoSett.request)) {
      protoSett.request = `game.${protoSett.request}`
    }
    protoSett = {
      request: 'game.CS_GM_QUERY',
      response: 'SC_GM_QUERY',
      ...protoSett
    }
  }
  return protoSett
}

const isProtoSett = setting => !setting ? ErrorInfo(CODE.ERROR_PROTO_NOT_API) : null

export const filter = (value, type = 'string') => {
  if (type === 'date') {
    return _.toInteger(moment(value).format('x'))
  }
  if (type === 'int') {
    return _.toInteger(value)
  }
  return value
}

export const types = {
  ['string']: value => _.isString(value) ,
  ['int']: value => _.isInteger(value),
  ['uid']: value => /[\d]+/.test(value) ,
  ['date']: value => moment(value).isValid()
}
